#include "max30102.h"

// 根据数据手册，MAX30102的I2C写地址是0xAE，读地址是0xAF
// 7位地址为0x57 (0xAE >> 1 = 0x57)
#define MAX30102_I2C_ADDR 0x57

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
static rt_bool_t initialized = RT_FALSE;

// I2C写入函数
static rt_err_t max30102_write_reg(uint8_t reg, uint8_t data)
{
    rt_uint8_t buf[2];
    struct rt_i2c_msg msgs;

    buf[0] = reg;
    buf[1] = data;

    msgs.addr = MAX30102_I2C_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 2;

    if (rt_i2c_transfer(i2c_bus, &msgs, 1) != 1)
    {
        rt_kprintf("I2C write failed: reg=0x%02x, data=0x%02x\n", reg, data);
        return RT_ERROR;
    }
    return RT_EOK;
}

// I2C读取函数
static rt_err_t max30102_read_reg(uint8_t reg, uint8_t *data)
{
    struct rt_i2c_msg msgs[2];

    msgs[0].addr = MAX30102_I2C_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = &reg;
    msgs[0].len = 1;

    msgs[1].addr = MAX30102_I2C_ADDR;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf = data;
    msgs[1].len = 1;

    if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
    {
        rt_kprintf("I2C read failed: reg=0x%02x\n", reg);
        return RT_ERROR;
    }
    return RT_EOK;
}

// 批量读取寄存器
static rt_err_t max30102_read_regs(uint8_t reg, uint8_t *data, uint16_t len)
{
    struct rt_i2c_msg msgs[2];

    msgs[0].addr = MAX30102_I2C_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = &reg;
    msgs[0].len = 1;

    msgs[1].addr = MAX30102_I2C_ADDR;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf = data;
    msgs[1].len = len;

    if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
    {
        rt_kprintf("I2C bulk read failed: reg=0x%02x, len=%d\n", reg, len);
        return RT_ERROR;
    }
    return RT_EOK;
}

// 读取FIFO中可用的样本数
rt_err_t max30102_read_fifo_count(uint8_t *available_samples)
{
    uint8_t wr_ptr, rd_ptr;
    rt_err_t ret;
    
    ret = max30102_read_reg(MAX30102_REG_FIFO_WR_PTR, &wr_ptr);
    if (ret != RT_EOK) return ret;
    
    ret = max30102_read_reg(MAX30102_REG_FIFO_RD_PTR, &rd_ptr);
    if (ret != RT_EOK) return ret;
    
    // 计算可用样本数（考虑FIFO循环）
    if (wr_ptr >= rd_ptr) {
        *available_samples = wr_ptr - rd_ptr;
    } else {
        *available_samples = 32 - rd_ptr + wr_ptr;
    }
    
    return RT_EOK;
}

// 初始化MAX30102传感器
rt_err_t max30102_init(const char *i2c_name)
{
    uint8_t id, rev_id;
    rt_err_t ret;
    int retry_count = 5;

    if (initialized)
    {
        rt_kprintf("MAX30102 already initialized\n");
        return RT_EOK;
    }

    // 查找I2C总线设备，获取I2C总线设备句柄
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(i2c_name);
    if (i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s device!\n", i2c_name);
        return RT_ERROR;
    }

    ret = rt_device_open(&(i2c_bus->parent), RT_DEVICE_OFLAG_RDWR);
    if (RT_EOK != ret)
    {
        rt_kprintf("open device failed: %d\n", ret);
        return RT_ERROR;
    }

    // 重试读取设备ID
    while (retry_count-- > 0)
    {
        ret = max30102_read_reg(MAX30102_REG_PART_ID, &id);
        if (ret == RT_EOK)
        {
            rt_kprintf("MAX30102 PART ID: 0x%02x\n", id);
            
            // 根据数据手册，PART ID应该是0x15
            if (id == 0x15)
            {
                // 读取版本ID
                max30102_read_reg(MAX30102_REG_REV_ID, &rev_id);
                rt_kprintf("MAX30102 found! PART ID:0x%02x, REV ID:0x%02x\n", id, rev_id);
                break;
            }
        }
        
        rt_kprintf("MAX30102 probe failed, retry %d\n", retry_count);
        rt_thread_mdelay(200);
    }

    if (ret != RT_EOK || id != 0x15)
    {
        rt_kprintf("MAX30102 not found after retries! Last ID:0x%02x\n", id);
        return RT_ERROR;
    }

    // 软复位 - 设置RESET位（第6位）
    if (max30102_write_reg(MAX30102_REG_MODE_CONFIG, 0x40) != RT_EOK)
    {
        rt_kprintf("Failed to reset MAX30102\n");
        return RT_ERROR;
    }
    rt_thread_mdelay(100);

    // 清除FIFO指针
    max30102_write_reg(MAX30102_REG_FIFO_WR_PTR, 0x00);
    max30102_write_reg(MAX30102_REG_OVF_COUNTER, 0x00);
    max30102_write_reg(MAX30102_REG_FIFO_RD_PTR, 0x00);

    // 配置FIFO (0x08)
    // SMP_AVE[2:0]=010 (4样本平均), FIFO_ROLLOVER_EN=1, FIFO_A_FULL[3:0]=1111 (几乎满阈值15)
    if (max30102_write_reg(MAX30102_REG_FIFO_CONFIG, 0x4F) != RT_EOK)
    {
        rt_kprintf("Failed to configure FIFO\n");
        return RT_ERROR;
    }
    
    // 配置SpO2参数 (0x0A)
    // SPO2_ADC_RGE[1:0]=01 (4096nA), SPO2_SR[2:0]=001 (100Hz), LED_PW[1:0]=11 (411μs, 18位)
    if (max30102_write_reg(MAX30102_REG_SPO2_CONFIG, 0x27) != RT_EOK)
    {
        rt_kprintf("Failed to configure SPO2 settings\n");
        return RT_ERROR;
    }

    // 配置LED电流 (0x0C, 0x0D)
    // 根据数据手册表8，0x24 = 36mA (近似值)
    if (max30102_write_reg(MAX30102_REG_LED1_PA, 0x24) != RT_EOK) // 红光LED
    {
        rt_kprintf("Failed to configure Red LED current\n");
        return RT_ERROR;
    }
    
    if (max30102_write_reg(MAX30102_REG_LED2_PA, 0x24) != RT_EOK) // 红外光LED
    {
        rt_kprintf("Failed to configure IR LED current\n");
        return RT_ERROR;
    }

    // 配置多LED控制寄存器 - SpO2模式 (Red + IR)
    // SLOT1 = Red, SLOT2 = IR
    if (max30102_write_reg(MAX30102_REG_MULTI_LED_CTRL1, 0x21) != RT_EOK) // SLOT1=001, SLOT2=010
    {
        rt_kprintf("Failed to configure multi-LED control\n");
        return RT_ERROR;
    }

    // 设置为SpO2模式 (Red + IR LEDs)
    if (max30102_write_reg(MAX30102_REG_MODE_CONFIG, MAX30102_MODE_SPO2) != RT_EOK)
    {
        rt_kprintf("Failed to set SPO2 mode\n");
        return RT_ERROR;
    }

    // 使能数据就绪中断
    if (max30102_write_reg(MAX30102_REG_INT_ENABLE1, MAX30102_INT_PPG_RDY) != RT_EOK)
    {
        rt_kprintf("Failed to enable interrupts\n");
        return RT_ERROR;
    }
    
    initialized = RT_TRUE;
    rt_kprintf("MAX30102 initialized successfully\n");

    rt_device_close(&(i2c_bus->parent));
    return RT_EOK;
}

// 读取温度传感器
rt_err_t max30102_read_temperature(float *temperature)
{
    uint8_t temp_int, temp_frac;
    rt_err_t ret;
    
    // 启动温度转换
    ret = max30102_write_reg(MAX30102_REG_TEMP_CONFIG, 0x01);
    if (ret != RT_EOK) return ret;
    
    // 等待转换完成
    rt_thread_mdelay(100);
    
    // 读取整数部分
    ret = max30102_read_reg(MAX30102_REG_TEMP_INTEGER, &temp_int);
    if (ret != RT_EOK) return ret;
    
    // 读取小数部分
    ret = max30102_read_reg(MAX30102_REG_TEMP_FRACTION, &temp_frac);
    if (ret != RT_EOK) return ret;
    
    // 温度计算：整数 + 小数 * 0.0625
    // 注意：整数部分使用2的补码表示
    int8_t temp_signed = (int8_t)temp_int;
    *temperature = temp_signed + (temp_frac & 0x0F) * 0.0625f;
    
    return RT_EOK;
}

// 读取原始传感器数据
rt_err_t max30102_read_data(max30102_data_t *data)
{
    uint8_t buf[6];
    rt_err_t ret;

    // 批量读取6字节FIFO数据 (Red: 3字节 + IR: 3字节)
    ret = max30102_read_regs(MAX30102_REG_FIFO_DATA, buf, 6);
    if (ret != RT_EOK)
    {
        rt_kprintf("Failed to read FIFO data\n");
        return ret;
    }

    // 解析数据 - 数据是左对齐的18位值
    // 根据数据手册，FIFO数据是左对齐的，我们需要右移6位来获取实际的18位值
    data->red = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2];
    data->red >>= 6;  // 右移6位得到18位有效数据
    
    data->ir = ((uint32_t)buf[3] << 16) | ((uint32_t)buf[4] << 8) | buf[5];
    data->ir >>= 6;   // 右移6位得到18位有效数据

    return RT_EOK;
}

// 简化的血氧和心率计算（实际应用需使用专业算法）
void max30102_calculate(max30102_data_t *data, max30102_result_t *result)
{
    static uint32_t red_buffer[32] = {0};
    static uint32_t ir_buffer[32] = {0};
    static uint8_t buffer_index = 0;
    static uint32_t sample_count = 0;
    
    // 存储当前样本到缓冲区
    red_buffer[buffer_index] = data->red;
    ir_buffer[buffer_index] = data->ir;
    buffer_index = (buffer_index + 1) % 32;
    sample_count++;
    
    // 每32个样本计算一次
    if (sample_count >= 32)
    {
        uint32_t red_sum = 0, ir_sum = 0;
        uint32_t red_min = UINT32_MAX, red_max = 0;
        uint32_t ir_min = UINT32_MAX, ir_max = 0;
        
        // 计算统计信息
        for (int i = 0; i < 32; i++)
        {
            red_sum += red_buffer[i];
            ir_sum += ir_buffer[i];
            
            if (red_buffer[i] < red_min) red_min = red_buffer[i];
            if (red_buffer[i] > red_max) red_max = red_buffer[i];
            if (ir_buffer[i] < ir_min) ir_min = ir_buffer[i];
            if (ir_buffer[i] > ir_max) ir_max = ir_buffer[i];
        }
        
        // 简化的心率计算（基于AC/DC比值）
        if (ir_max > ir_min && red_max > red_min)
        {
            float ir_acdc = (float)(ir_max - ir_min) / ir_max;
            float red_acdc = (float)(red_max - red_min) / red_max;
            
            // 简化的心率估算（实际需要峰值检测算法）
            result->heart_rate = 60 + (uint32_t)(ir_acdc * 40);
            
            // 简化的血氧估算（实际需要比值R计算）
            float ratio_r = red_acdc / ir_acdc;
            result->spo2 = 95.0f - 25.0f * ratio_r;
            
            // 限制范围
            if (result->heart_rate < 40) result->heart_rate = 40;
            if (result->heart_rate > 180) result->heart_rate = 180;
            if (result->spo2 < 70.0f) result->spo2 = 70.0f;
            if (result->spo2 > 100.0f) result->spo2 = 100.0f;
        }
        else
        {
            // 默认值
            result->heart_rate = 75;
            result->spo2 = 98.0f;
        }
        
        sample_count = 0;
    }
    
    // 读取温度（不频繁读取）
    static uint32_t temp_counter = 0;
    if (temp_counter++ >= 100)  // 每100次采样读取一次温度
    {
        max30102_read_temperature(&result->temperature);
        temp_counter = 0;
    }
}

// 简化的RT-Thread传感器框架初始化函数
rt_err_t rt_hw_max30102_init(const char *i2c_name)
{
    return max30102_init(i2c_name);
}